第13章 LangChain向量数据库集成
学习目标
- 理解LangChain向量存储抽象层的设计与工作原理
- 掌握主流向量数据库与LangChain的集成方法
- 学习如何构建基于向量数据库的知识检索系统
- 了解向量检索的高级优化技术
LangChain中的向量存储抽象
LangChain提供了统一的向量存储抽象层,使开发者能够轻松地切换不同的向量数据库,而不需要修改上层应用逻辑。
参考课程视频中的内容
1. 向量存储的核心概念
在LangChain中,向量存储抽象包含以下核心概念:
- Documents:要索引的文本文档,可以包含元数据
- Embeddings:将文本转换为向量的模型
- VectorStore:存储和检索向量的数据库
- Retrievers:从向量存储中检索相关文档的接口
2. 向量存储的基本功能
LangChain的向量存储抽象提供了以下基本功能:
- 添加文档:将文档转换为向量并存储
- 相似性搜索:根据查询向量查找最相似的文档
- 过滤搜索:根据元数据过滤搜索结果
- 作为检索器:提供标准化的检索接口
集成主流向量数据库
LangChain支持多种向量数据库的集成,下面我们将介绍几种常用的向量数据库的使用方法。
1. Chroma
Chroma是一个轻量级的开源向量数据库,非常适合本地开发和小型应用。
python
from langchain.vectorstores import Chroma
from langchain.embeddings import DeepSeekEmbeddings
from langchain.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
# 初始化Embedding模型
embeddings = DeepSeekEmbeddings(api_key="your-api-key")
# 加载文档
loader = TextLoader("./data/documents.txt")
documents = loader.load()
# 文本分割
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)
# 创建Chroma向量存储
vectorstore = Chroma.from_documents(
documents=docs,
embedding=embeddings,
persist_directory="./chroma_db" # 持久化存储路径
)
# 相似性搜索
query = "人工智能的伦理问题"
results = vectorstore.similarity_search(query, k=3)
for doc in results:
print(doc.page_content)
print(doc.metadata)
print("---")
# 持久化
vectorstore.persist()
# 加载已有的向量存储
loaded_vectorstore = Chroma(
persist_directory="./chroma_db",
embedding_function=embeddings
)
2. FAISS
FAISS是Facebook AI开发的高性能向量搜索库,支持大规模向量索引和高效检索。
python
from langchain.vectorstores import FAISS
# 创建FAISS向量存储
vectorstore = FAISS.from_documents(docs, embeddings)
# 相似性搜索
results = vectorstore.similarity_search_with_score(query, k=3)
for doc, score in results:
print(f"Score: {score}")
print(doc.page_content)
print("---")
# 保存到磁盘
vectorstore.save_local("./faiss_index")
# 从磁盘加载
loaded_vectorstore = FAISS.load_local("./faiss_index", embeddings)
3. Pinecone
Pinecone是一个云托管的向量数据库服务,提供高性能和可扩展的向量搜索。
python
import os
from langchain.vectorstores import Pinecone
import pinecone
# 初始化Pinecone
pinecone.init(
api_key=os.environ["PINECONE_API_KEY"],
environment=os.environ["PINECONE_ENVIRONMENT"]
)
# 创建索引(如果不存在)
index_name = "langchain-demo"
if index_name not in pinecone.list_indexes():
pinecone.create_index(
name=index_name,
dimension=1536, # 根据embedding模型维度设置
metric="cosine"
)
# 创建Pinecone向量存储
vectorstore = Pinecone.from_documents(
docs,
embeddings,
index_name=index_name
)
# 相似性搜索
results = vectorstore.similarity_search(
query,
k=3,
filter={"category": "AI research"} # 元数据过滤
)
4. Milvus
Milvus是一个开源的向量数据库,支持大规模向量搜索和存储。
python
from langchain.vectorstores import Milvus
# 连接Milvus服务
vectorstore = Milvus.from_documents(
docs,
embeddings,
connection_args={
"host": "localhost",
"port": "19530"
},
collection_name="langchain_collection"
)
# 相似性搜索
results = vectorstore.similarity_search(query, k=3)
5. 集成DeepSeek Embeddings
LangChain可以轻松集成DeepSeek的embedding模型:
python
from langchain.embeddings import DeepSeekEmbeddings
from langchain.vectorstores import Chroma
# 初始化DeepSeek embeddings
embeddings = DeepSeekEmbeddings(api_key="your-api-key")
# 创建向量存储
vectorstore = Chroma.from_documents(docs, embeddings)
# 查询
query = "DeepSeek AI的特点和优势"
results = vectorstore.similarity_search(query, k=3)
构建知识检索系统
1. 基础检索问答系统
使用向量数据库构建简单的检索问答系统:
python
from langchain.chains import RetrievalQA
from langchain.llms import DeepSeek
# 初始化LLM
llm = DeepSeek(api_key="your-api-key")
# 创建检索器
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
# 创建检索问答链
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff", # 直接将所有检索文档拼接作为上下文
retriever=retriever,
verbose=True
)
# 执行问答
question = "DeepSeek模型有哪些应用场景?"
answer = qa_chain.run(question)
print(answer)
2. 构建对话式检索问答系统
加入对话历史的检索问答系统:
python
from langchain.chains import ConversationalRetrievalChain
from langchain.memory import ConversationBufferMemory
# 初始化记忆组件
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True
)
# 创建对话式检索问答链
qa_chain = ConversationalRetrievalChain.from_llm(
llm=llm,
retriever=retriever,
memory=memory,
verbose=True
)
# 第一轮对话
response = qa_chain({"question": "什么是大语言模型?"})
print(response["answer"])
# 第二轮对话(引用前文信息)
response = qa_chain({"question": "它们有哪些局限性?"})
print(response["answer"])
3. 支持元数据过滤的检索问答系统
实现基于元数据过滤的检索问答系统:
python
from langchain.chains import RetrievalQA
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMChainFilter
# 创建元数据过滤器
metadata_filter_prompt = """
你是一个文档过滤专家。你需要判断以下文档是否与查询"{query}"相关。
该文档具有以下元数据:
- 类别: {category}
- 日期: {date}
- 作者: {author}
文档内容:
{page_content}
这个文档是否与查询"{query}"相关?请只回答"是"或"否"。
"""
filter_prompt = PromptTemplate(
input_variables=["query", "page_content", "category", "date", "author"],
template=metadata_filter_prompt
)
llm_filter = LLMChainFilter.from_llm(
llm=llm,
prompt=filter_prompt
)
# 创建带过滤的检索器
base_retriever = vectorstore.as_retriever(search_kwargs={"k": 10})
compression_retriever = ContextualCompressionRetriever(
base_compressor=llm_filter,
base_retriever=base_retriever
)
# 创建检索问答链
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=compression_retriever,
verbose=True
)
# 执行问答
answer = qa_chain.run("DeepSeek在金融领域的应用")
print(answer)
向量检索的高级优化
1. 混合检索策略
结合关键词和向量检索的混合检索策略:
python
from langchain.retrievers import BM25Retriever, EnsembleRetriever
# 创建BM25检索器(基于关键词)
bm25_retriever = BM25Retriever.from_documents(docs)
bm25_retriever.k = 5 # 返回5个文档
# 创建向量检索器
vector_retriever = vectorstore.as_retriever(search_kwargs={"k": 5})
# 创建混合检索器
ensemble_retriever = EnsembleRetriever(
retrievers=[bm25_retriever, vector_retriever],
weights=[0.3, 0.7] # 权重分配
)
# 使用混合检索
results = ensemble_retriever.get_relevant_documents(query)
2. 自查询检索
使用LLM动态生成检索查询和过滤条件:
python
from langchain.retrievers import SelfQueryRetriever
from langchain.chains.query_constructor.base import AttributeInfo
# 定义可查询的元数据字段
metadata_field_info = [
AttributeInfo(
name="category",
description="文档的类别,如'AI研究'、'产品介绍'等",
type="string"
),
AttributeInfo(
name="date",
description="文档的发布日期,格式为YYYY-MM-DD",
type="date"
),
AttributeInfo(
name="author",
description="文档的作者姓名",
type="string"
)
]
# 创建自查询检索器
document_content_description = "关于AI和大语言模型的文档"
retriever = SelfQueryRetriever.from_llm(
llm=llm,
vectorstore=vectorstore,
document_contents=document_content_description,
metadata_field_info=metadata_field_info,
verbose=True
)
# 使用自然语言查询(包含过滤条件)
results = retriever.get_relevant_documents(
"查找2023年1月后发布的关于DeepSeek金融应用的文档"
)
3. 层次化检索
实现层次化检索策略,提高大规模文档检索的效率:
python
from langchain.retrievers import ParentDocumentRetriever
from langchain.storage import InMemoryStore
from langchain.text_splitter import RecursiveCharacterTextSplitter
# 创建文档拆分器
parent_splitter = RecursiveCharacterTextSplitter(chunk_size=2000, chunk_overlap=200)
child_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
# 创建文档存储
docstore = InMemoryStore()
# 创建层次化检索器
retriever = ParentDocumentRetriever(
vectorstore=vectorstore,
docstore=docstore,
parent_splitter=parent_splitter,
child_splitter=child_splitter
)
# 添加文档
retriever.add_documents(documents)
# 检索
results = retriever.get_relevant_documents(query)
4. 多查询检索
利用LLM生成多个查询变体提高检索效果:
python
from langchain.retrievers.multi_query import MultiQueryRetriever
# 创建多查询检索器
retriever = MultiQueryRetriever.from_llm(
retriever=vectorstore.as_retriever(),
llm=llm
)
# 使用多查询检索
queries = "DeepSeek模型如何用于自然语言处理?"
results = retriever.get_relevant_documents(queries)
5. RAG融合检索与生成
实现检索增强生成(RAG)系统,结合检索与生成能力:
python
from langchain.chains import RetrievalQA, LLMChain
from langchain.prompts import PromptTemplate
# 创建RAG提示模板
rag_prompt_template = """
请基于以下检索到的上下文信息,回答用户的问题。如果检索的信息不足以回答问题,请清楚地说明,不要编造信息。
上下文:
{context}
用户问题: {question}
详细回答:
"""
rag_prompt = PromptTemplate(
template=rag_prompt_template,
input_variables=["context", "question"]
)
# 创建检索QA链
qa = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=retriever,
chain_type_kwargs={"prompt": rag_prompt},
return_source_documents=True
)
# 执行RAG
result = qa({"query": "DeepSeek如何处理多语言任务?"})
print(result["result"])
print("\n来源文档:")
for doc in result["source_documents"]:
print(f"- {doc.metadata.get('source', 'unknown')}")
思考题
- 对比不同向量数据库的性能和特性,你会在什么情况下选择Chroma、FAISS、Pinecone或Milvus?
- 如何评估向量检索系统的效果?有哪些指标可以用来衡量检索的准确性和相关性?
- 在处理大规模文档集时,如何优化向量检索的性能和资源消耗?
- 设计一个混合检索策略,结合向量检索、关键词检索和元数据过滤,如何实现这个系统?
接下来,我们将探讨如何将LangChain与搜索和向量数据库结合,构建完整的RAG应用。